// Copyright 2001
// Kenneth A. Lambert and Martin Osborne
package TurtleGraphics;
import javax.swing.*;
import java.awt.*;
import java.io.*;
import java.awt.event.*;
/**
* The class GBFrame (short for Grid Bag Frame) provides a high-level application window.
* The window comes with a built in GridBagLayout. Components are added
* to the window by specifying their row position, column position, width (in columns),
* and height (in rows)in the grid.
* <BR>
* <BR>
* Events of different types, such as button clicks and menu item selections,
* are handled by implementing the appropriate GBFrame methods in the application.
* <BR>
* <BR>
* Example use of GBFrame:
*
* <pre>
* // Hello world application with BreezySwing.<BR>
* import javax.swing.*;
* import BreezySwing.*;<BR>
*
* public class HelloWorld extends GBFrame{<BR>
*
* // Add a labeled button to the window at row 1, column 1, width 1, height 1.
* JButton clickMe = addButton("Click me", 1, 1, 1, 1);<BR>
*
* // Implement the method to handle the button click.
* public void buttonClicked(JButton buttonObj){
* messageBox("Hello world!");
* }<BR>
*
* // Implement the method that runs when the application is launched.
* public static void main(String[] args){
* Frame frm = new HelloWorld();
* frm.setSize(100, 100);
* frm.setVisible(true);
* }
* }
* </pre>
*/
public class GBFrame extends JFrame{
GridBagLayout gbl = new GridBagLayout();
GridBagConstraints gbc = new GridBagConstraints();
JMenuBar menuBar = new JMenuBar();
GBFrameWindowListener windowListener;
Container contentPane;
/**
* Creates a GBFrame application window.
*/
public GBFrame(){
contentPane = getContentPane();
contentPane.setLayout(gbl);
gbc.weightx = 100;
gbc.weighty = 100;
gbc.insets.bottom = 1;
gbc.insets.left = 2;
gbc.insets.right = 2;
gbc.insets.top = 1;
setTitle(" ");
windowListener = new GBFrameWindowListener(this);
addWindowListener(windowListener);
}
/**
* Used with non-GUI applications (tester programs) to pause execution
* until the user hits the Enter key.
* Prevents a "fly-by" disappearance of the terminal window
* in some environments by pausing execution until the user
* hits the Enter key. Usage: GBFrame.pause();
*/
public static void pause(){
System.out.print ("\nHit Enter to continue: ");
try {
InputStreamReader reader = new InputStreamReader (System.in);
BufferedReader buffer = new BufferedReader (reader);
buffer.readLine();
}
catch (IOException e){
System.exit(0);
}
}
/**
* Allows the application to set the look and feel of the window
* and all its subcomponents to a platform-specific look and feel.
* If no event handling is desired, this method need not be implemented.
* @param type A String, either "METAL", "MOTIF", or "OTHER"
*/
public void setLookAndFeel(String type){
int value = 0;
UIManager.LookAndFeelInfo[] looks;
looks = UIManager.getInstalledLookAndFeels();
if (type.equalsIgnoreCase("METAL"))
value = 0;
else if (type.equalsIgnoreCase("MOTIF"))
value = 1;
else
value = 2;
try{
UIManager.setLookAndFeel(looks[value].getClassName());
SwingUtilities.updateComponentTreeUI(this);
}catch(Exception e){
messageBox("Error: \n" + e.toString());
}
}
public void setSize(int width, int height){
super.setSize(width, height);
if (menuBar.getMenuCount() > 0)
setJMenuBar (menuBar);
}
/**
* Pops up a message box containing the number and an OK button.
*/
public void messageBox (double num){
MessageBox mb = new MessageBox (this, "" + num);
mb.show();
}
/**
* Pops up a message box containing the string and an OK button.
*/
public void messageBox (String msg){
MessageBox mb = new MessageBox (this, msg);
mb.show();
}
/**
* Pops up a message box containing the string representation of the object and an OK button.
*/
public void messageBox (Object msg){
MessageBox mb = new MessageBox (this, msg.toString());
mb.show();
}
public void messageBox (double num, int width, int height){
MessageBox mb = new MessageBox (this, "" + num);
mb.setSize(width, height);
mb.show();
}
public void messageBox (String msg, int width, int height){
MessageBox mb = new MessageBox (this, msg);
mb.setSize(width, height);
mb.show();
}
public void messageBox (Object msg, int width, int height){
MessageBox mb = new MessageBox (this, msg.toString());
mb.setSize(width, height);
mb.show();
}
// Abstract event handlers for menus, buttons, lists, and mice.
/**
* The application must implement this method in order to handle menu events. If no menus
* are added to the window, this method need not be implemented.
* @param mi The MenuItem in which the selection occurred.
* Example:
* <pre>
* // Add the menu items to the window.
* JMenuItem newFileMI = addMenuItem("File", "New");
* JMenuItem openFileMI = addMenuItem("File", "Open");
* JMenuItem saveFileMI = addMenuItem("File", "Save");
* // Handle the menu selection.
* public void menuItemSelected(JMenuItem mi){
* if (mi == newFileMI)
* messageBox("File/New selected");
* else if (mi == openFileMI)
* messageBox("File/Open selected");
* else
* messageBox("File/Save selected");
* }
* </pre>
*/
public void menuItemSelected (JMenuItem mi){
messageBox ("You need a 'menuItemSelected' method");
}
/**
* The application must implement this method in order to handle a selection
* (single click) on an item in a scrolling list.
* If no event handling is desired, this method need not be implemented.
* @param listObj The JList in which the selection occurred.
*/
public void listItemSelected (JList listObj){
}
/**
* The application must implement this method in order to handle button clicks.
* If no buttons are added to the window, this method need not be implemented.
* @param buttonObj The JButton in which the click occurred.
* Example:
* <pre>
* // Add the buttons to the window.
* JButton okButton = addButton("OK", 1, 1, 1, 1);
* JButton cancelButton = addButton("Cancel", 1, 2, 1, 1);
* // Handle the button selection.
* public void buttonClicked(JButton buttonObj){
* if (buttonObj == okButton)
* messageBox("OK selected");
* else
* messageBox("Cancel selected");
* }
* </pre>
*/
public void buttonClicked(JButton buttonObj){
messageBox ("You need a 'buttonClicked' method");
}
/**
* The application must implement this method in order to handle a
* double click on an item in a scrolling list.
* If no double click is anticipated, this method need not be implemented.
* @param listObj The JList in which the double click occurred.
* @param itemClicked The string selected by the double click.
*/
public void listDoubleClicked (JList listObj, String itemClicked){
messageBox ("You need a 'listDoubleClicked' method");
}
// Methods to add window objects to the interface. Listeners
// are added for menu items, buttons, and lists.
/**
* Adds an item with the specified name to a menu with the specified name
* in the window.
* @param menuName The name of the menu.
* @param item name The name of the menu item (selection).
* @return The JMenuItem.
* Example:
* <pre>
* JMenuItem newFileMI = addMenuItem("File", "New");
* JMenuItem openFileMI = addMenuItem("File", "Open");
* JMenuItem saveFileMI = addMenuItem("File", "Save");
* </pre>
*/
public JMenuItem addMenuItem (String menuName, String itemName){
JMenu menu = null;
int i;
for (i = 0; i < menuBar.getMenuCount(); i++){
menu = menuBar.getMenu (i);
if (menuName.equals (menu.getText())) break;
}
if (i == menuBar.getMenuCount()){
menu = new JMenu (menuName);
menuBar.add (menu);
}
JMenuItem menuItem = new JMenuItem (itemName);
menuItem.addActionListener(new GBFrameMenuListener(this));
menu.add (menuItem);
return menuItem;
}
/**
* Adds a label with the specified name to the specified position, with the specified
* width and height.
* @param text The name of the label.
* @param row The beginning row (starting from 1) of the window's grid in which the label is displayed.
* @param col The beginning column (starting from 1) of the window's grid in which the label is displayed.
* @param width The number of columns of the window's grid occuppied by the label.
* @param height The number of rows of the window's grid occuppied by the label.
* @return the JLabel
*/
public JLabel addLabel (String text, int row, int col, int width, int height){
gbc.fill = GridBagConstraints.NONE;
gbc.anchor = GridBagConstraints.NORTHWEST;
JLabel control = new JLabel (text);
add (control, row, col, width, height);
return control;
}
/**
* Adds a JButton with the specified name to the specified position, with the specified
* width and height.
* @param text The name of the Button.
* @param row The beginning row (starting from 1) of the window's grid in which the Button is displayed.
* @param col The beginning column (starting from 1) of the window's grid in which the Button is displayed.
* @param width The number of columns of the window's grid occuppied by the Button.
* @param height The number of rows of the window's grid occuppied by the Button.
* @return the button.
* Example:
* <pre>
* JButton okButton = addButton("OK", 1, 1, 1, 1);
* // Adds a button at position row 1, column 1,
* // with a width of 1 column and a height of one row.
* </pre>
*/
public JButton addButton (String text, int row, int col, int width, int height){
gbc.fill = GridBagConstraints.NONE;
gbc.anchor = GridBagConstraints.CENTER;
JButton control = new JButton (text);
control.addActionListener(new GBFrameButtonListener(this));
add (control, row, col, width, height);
return control;
}
/**
* Adds a JTextField containing the specified string to the specified position, with the specified
* width and height.
* @param text The string to be displayed initially.
* @param row The beginning row (starting from 1) of the window's grid in which the JTextField is displayed.
* @param col The beginning column (starting from 1) of the window's grid in which the JTextField is displayed.
* @param width The number of columns of the window's grid occuppied by the JTextField.
* @param height The number of rows of the window's grid occuppied by the JTextField.
* @return the JTextField.
*/
public JTextField addTextField (String text, int row, int col, int width, int height){
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.anchor = GridBagConstraints.NORTHWEST;
JTextField control = new JTextField (text);
add (control, row, col, width, height);
return control;
}
/**
* Adds a JTextArea containing the specified string to the specified position, with the specified
* width and height.
* @param text The string to be displayed initially.
* @param row The beginning row (starting from 1) of the window's grid in which the JTextArea is displayed.
* @param col The beginning column (starting from 1) of the window's grid in which the JTextArea is displayed.
* @param width The number of columns of the window's grid occuppied by the JTextArea.
* @param height The number of rows of the window's grid occuppied by the JTextArea.
* @return the TextArea.
*/
public JTextArea addTextArea (String text, int row, int col, int width, int height){
gbc.fill = GridBagConstraints.BOTH;
gbc.anchor = GridBagConstraints.NORTHWEST;
gbc.weightx = 500;
gbc.weighty = 500;
JTextArea control = new JTextArea (text); //, height*2, width*15);
add (new JScrollPane(control), row, col, width, height);
gbc.weightx = 100;
gbc.weighty = 100;
control.setFont (new Font ("Courier", Font.PLAIN, 12));
return control;
}
/**
* Adds a JList (a scrolling list) to the specified position, with the specified
* width and height.
* @param row The beginning row (starting from 1) of the window's grid in which the JList is displayed.
* @param col The beginning column (starting from 1) of the window's grid in which the JList is displayed.
* @param width The number of columns of the window's grid occuppied by the JList.
* @param height The number of rows of the window's grid occuppied by the JList.
* @return the JList
*/
public JList addList (int row, int col, int width, int height){
gbc.fill = GridBagConstraints.BOTH;
gbc.anchor = GridBagConstraints.NORTHWEST;
gbc.weightx = 500;
gbc.weighty = 500;
JList control = new JList (new DefaultListModel()); //height*2, false);
control.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
control.addMouseListener(new GBFrameDCListener(control, this));
add (new JScrollPane(control), row, col, width, height);
gbc.weightx = 100;
gbc.weighty = 100;
return control;
}
/**
* Adds a JComboBox (pull down list) to the specified position, with the specified
* width and height.
* @param row The beginning row (starting from 1) of the window's grid in which the JComboBox is displayed.
* @param col The beginning column (starting from 1) of the window's grid in which the JComboBox is displayed.
* @param width The number of columns of the window's grid occuppied by the JComboBox.
* @param height The number of rows of the window's grid occuppied by the JComboBox.
* @return the JComboBox.
*/
public JComboBox addComboBox (int row, int col, int width, int height){
gbc.fill = GridBagConstraints.NONE;
gbc.anchor = GridBagConstraints.NORTHWEST;
JComboBox control = new JComboBox();
add (control, row, col, width, height);
return control;
}
/**
* Adds an IntegerField containing the specified integer to the specified position, with the specified
* width and height.
* @param num The integer to be displayed initially.
* @param row The beginning row (starting from 1) of the window's grid in which the IntegerField is displayed.
* @param col The beginning column (starting from 1) of the window's grid in which the IntegerField is displayed.
* @param width The number of columns of the window's grid occuppied by the IntegerField.
* @param height The number of rows of the window's grid occuppied by the IntegerField.
* @returns the IntegerField.
*/
public IntegerField addIntegerField (int num, int row, int col, int width, int height){
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.anchor = GridBagConstraints.NORTHWEST;
IntegerField control = new IntegerField (num);
add (control, row, col, width, height);
return control;
}
/**
* Adds a DoubleField containing the specified number to the specified position, with the specified
* width and height.
* @param num The number to be displayed initially.
* @param row The beginning row (starting from 1) of the window's grid in which the DoubleField is displayed.
* @param col The beginning column (starting from 1) of the window's grid in which the DoubleField is displayed.
* @param width The number of columns of the window's grid occuppied by the DoubleField.
* @param height The number of rows of the window's grid occuppied by the DoubleField.
* @returns the DoubleField.
*/
public DoubleField addDoubleField (double num, int row, int col, int width, int height){
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.anchor = GridBagConstraints.NORTHWEST;
DoubleField control = new DoubleField (num);
add (control, row, col, width, height);
return control;
}
/**
* Adds a JCheckBox to the specified position, with the specified
* width and height.
* @param row The beginning row (starting from 1) of the window's grid in which the JCheckBox is displayed.
* @param col The beginning column (starting from 1) of the window's grid in which the JCheckBox is displayed.
* @param width The number of columns of the window's grid occuppied by the JCheckBox.
* @param height The number of rows of the window's grid occuppied by the JCheckBox.
* @return the JCheckBox.
*/
public JCheckBox addCheckBox (String text, int row, int col, int width, int height){
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.anchor = GridBagConstraints.NORTHWEST;
JCheckBox control = new JCheckBox (text);
add (control, row, col, width, height);
return control;
}
/**
* Adds a JRadioButton to the specified position, with the specified
* width and height.
* @param row The beginning row (starting from 1) of the window's grid in which the JRadioButton is displayed.
* @param col The beginning column (starting from 1) of the window's grid in which the JRadioButton is displayed.
* @param width The number of columns of the window's grid occuppied by the JRadioButton.
* @param height The number of rows of the window's grid occuppied by the JRadioButton.
* @return the JRadioButton.
*/
public JRadioButton addRadioButton (String text, int row, int col, int width, int height){
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.anchor = GridBagConstraints.NORTHWEST;
JRadioButton control = new JRadioButton (text);
add (control, row, col, width, height);
return control;
}
/**
* Adds a GBPanel to the specified position, with the specified
* width and height.
* @param row The beginning row (starting from 1) of the window's grid in which the GBPanel is displayed.
* @param col The beginning column (starting from 1) of the window's grid in which the GBPanel is displayed.
* @param width The number of columns of the window's grid occuppied by the GBPanel.
* @param height The number of rows of the window's grid occuppied by the GBPanel.
* @return the GBPanel.
*/
public GBPanel addPanel(GBPanel panel, int row, int col, int width, int height){
gbc.fill = GridBagConstraints.BOTH;
gbc.anchor = GridBagConstraints.NORTHWEST;
gbc.weightx = 500;
gbc.weighty = 500;
add (panel, row, col, width, height);
gbc.weightx = 100;
gbc.weighty = 100;
return panel;
}
private void add( Component c,int y, int x, int w, int h){
gbc.gridx = x-1;
gbc.gridy = y-1;
gbc.gridwidth = w;
gbc.gridheight = h;
gbl.setConstraints(c, gbc);
contentPane.add(c);
}
}
// Controller class to handle window event closing.
class GBFrameWindowListener extends WindowAdapter{
GBFrame myFrame;
public GBFrameWindowListener(GBFrame frm){
myFrame = frm;
}
public void windowClosing(WindowEvent e){
System.exit(0);
}
}
// Controller class to handle button events.
class GBFrameButtonListener implements ActionListener{
GBFrame myFrame;
public GBFrameButtonListener(GBFrame frm){
myFrame = frm;
}
public void actionPerformed(ActionEvent e){
myFrame.buttonClicked((JButton) e.getSource());
}
}
// Controller class to handle menu events.
class GBFrameMenuListener implements ActionListener{
GBFrame myFrame;
public GBFrameMenuListener(GBFrame frm){
myFrame = frm;
}
public void actionPerformed(ActionEvent e){
myFrame.menuItemSelected((JMenuItem) e.getSource());
}
}
// Controller class to handle list selection and double click events.
class GBFrameDCListener extends MouseAdapter{
private JList list;
private GBFrame frm;
public GBFrameDCListener(JList list, GBFrame frm){
this.list = list;
this.frm = frm;
}
public void mouseClicked(MouseEvent e) {
if (((DefaultListModel)list.getModel()).isEmpty())
return;
if (e.getClickCount() == 2) {
int index = list.locationToIndex(e.getPoint());
String s = (String) ((DefaultListModel) list.getModel()).elementAt(index);
frm.listDoubleClicked(list, s);
}
else if (e.getClickCount() == 1)
frm.listItemSelected(list);
}
}